/**
 * 
 */
package com.cea.papyrus.core.helper;

import java.util.Collection;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;

import com.cea.papyrus.core.utils.Debug;

/**
 * This registry register model helpers from the declared extensions.
 */
public class ModelerHelperExtensionRegistry extends ModelerHelperRegistry {

	/** ID of this helper extension */
    public static final String HELPER_EXTENSION_ID = "modelHelper";

    /** Debug channel for this class */
	private static final int channel = 31;

    /** Namespace used by the extension point. */
    protected String extensionPointNamespace;

    /** Are the declared extension loaded */
    private boolean isloaded;

    /**
     * 
     */
    public ModelerHelperExtensionRegistry(String extensionPointNamespace) {
        this.extensionPointNamespace = extensionPointNamespace;
    }

    @Override
    public Collection<IModelerHelper> getFactories() {
        if (!isloaded) {
            registerDeclaredExtensions();
        }
        return super.getFactories();
    }

    @Override
    public IModelerHelper getFactory(Class elementClass) {
        if (!isloaded) {
            registerDeclaredExtensions();
        }
        return super.getFactory(elementClass);
    }

    @Override
    public IModelerHelper getFactory(Object key) {
        if (!isloaded) {
            registerDeclaredExtensions();
        }
        return super.getFactory(key);
    }

    /**
     * Register declared extensions.
     */
    protected void registerDeclaredExtensions() {

        // Reading data from plugins
        IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(extensionPointNamespace, HELPER_EXTENSION_ID);

        for (IConfigurationElement ele : configElements) {
            IModelerHelper modelHelper;
            String id;
            if(Debug.debug) {
            	showConfElement(ele);
            }
            try {
                Debug.debug(this, "Create extension using provided method...", channel);
                modelHelper = (IModelerHelper) ele.createExecutableExtension("helperClass");
                id = ele.getAttribute("helperID");
                // register the helper
                if (id != null) {
                    registerFactory(id, modelHelper);
                } else { 
                    registerFactory(modelHelper);
                }
                Debug.debug(this, "Create extension done", channel);
            } catch (CoreException e1) {
                Debug.debug(this, "CoreException: "+e1.getMessage(), channel);
                continue;
            } catch (ClassCastException e1) {
            	Debug.debug(this, "ClassCastException: "+e1.getMessage(), channel);
                continue;
            }
        }
        // Mark as loaded
        isloaded = true;
    }

    /**
     * Output a configuration element. For debug purpose.
     * @param ele
     */
    private void showConfElement(IConfigurationElement ele) {
        Debug.debug(this, "<" + ele.getName(), channel);

        for (String name : ele.getAttributeNames()) {
        	Debug.debug(this, "\n   " + name + "='" + ele.getAttribute(name) + "'", channel);
        }
        
        if (ele.getChildren().length > 0) {
            Debug.debug(this, ">", channel);
            for (IConfigurationElement child : ele.getChildren()) {
                showConfElement(child);
            }
            Debug.debug(this, "</" + ele.getName() + ">", channel);
        } else {
        	Debug.debug(this, "/>", channel);
        }
    }

}
